/**
 * 
 */
package com.google.code.netz.wfe;

import com.google.code.netz.wfe.api.ILifecycleHandler;
import com.google.code.netz.wfe.api.IManaged;
import com.google.code.netz.wfe.api.WorkflowException;

/**
 * Provides a template for common bits of code that can inturn be used by
 * extensions.
 * 
 * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
 * @since 1.0
 * @version $Id$
 */
public abstract class AbstractLifecycleHandler<E extends IManaged> implements ILifecycleHandler<E> {

	/**
	 * Mutex to lock state updates to the managed PetriNetentity.
	 */
	private static Object mutex = new Object();

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.google.code.netz.wfe.api.ILifecycleHandler#resume(com.google.code.netz.wfe.api.IManaged,
	 *      java.lang.Object)
	 */
	@Override
	public void resume(E entity, Object workflowContext) throws WorkflowException {
		// TODO: Case status should be updated in a synchronized block
		// Resume Case only if it is suspended
		synchronized (mutex) {
			handleResume(entity, workflowContext);
		}

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.google.code.netz.wfe.api.ILifecycleHandler#start(com.google.code.netz.wfe.api.IManaged,
	 *      java.lang.Object)
	 */
	@Override
	public void start(E entity, Object workflowContext) throws WorkflowException {
		// TODO: Case status should be updated in a synchronized block
		// Resume Case only if it is suspended
		synchronized (mutex) {
			handleStart(entity, workflowContext);
		}
	}

	@Override
	public void stop(E entity, Object workflowContext) throws WorkflowException {
		// TODO: Case status should be updated in a synchronized block
		// Resume Case only if it is suspended
		synchronized (mutex) {
			handleStop(entity, workflowContext);
		}
	}

	@Override
	public void suspend(E entity, Object workflowContext) throws WorkflowException {
		// TODO: Case status should be updated in a synchronized block
		// Resume Case only if it is suspended
		synchronized (mutex) {
			handleSuspend(entity, workflowContext);
		}
	}

	/**
	 * Template method to the implemented by extension to resume the specified
	 * entity from suspended state.
	 * 
	 * @param entity
	 * @param workflowContext
	 * @throws WorkflowException
	 */
	protected abstract void handleResume(E entity, Object workflowContext) throws WorkflowException;

	/**
	 * Template method to the implemented by extension to start the specified
	 * entity from default state.
	 * 
	 * @param entity
	 * @param workflowContext
	 * @throws WorkflowException
	 */
	protected abstract void handleStart(E entity, Object workflowContext) throws WorkflowException;

	/**
	 * Template method to the implemented by extension to start the specified
	 * entity from default state.
	 * 
	 * @param entity
	 * @param workflowContext
	 * @throws WorkflowException
	 */
	protected abstract void handleStop(E entity, Object workflowContext) throws WorkflowException;

	/**
	 * Template method to the implemented by extension to start the specified
	 * entity from default state.
	 * 
	 * @param entity
	 * @param workflowContext
	 * @throws WorkflowException
	 */
	protected abstract void handleSuspend(E entity, Object workflowContext) throws WorkflowException;

}
